<template>
  <div class="wps-excel">
    <wps-edit-bar />
    <div v-if="!loaded" class="loading">
      <loading />
    </div>
    <div v-show="loaded" class="excel-view" ref="excelViewDom" v-html="excelHtml"></div>
    <ul v-show="loaded" class="excel-tabs">
      <li
        v-for="(item, index) in excelTabs"
        :key="index"
        :class="{ checked: currentExcel === index }"
        @click.stop="handleSelectTab(index)"
      >
        {{ item }}
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import WpsEditBar from '@/components/systemWindow/wps/wpsEditBar.vue'
import * as XLSX from 'xlsx'
import { ref, watch } from 'vue'
import { getWordName } from '@/utils/utils'
import type { PropType } from 'vue'

const props = defineProps({
  data: {
    type: String as PropType<string>,
    required: true
  }
})

const loaded = ref<boolean>(false)
const excelViewDom = ref<HTMLElement>()
const currentExcel = ref<number>(0)
const excelHtml = ref<string>('')
const excelTabs = ref<string[]>([])

const getExcelHeaderCol = (json: unknown[]): number => {
  let max = 0
  json.forEach((item) => {
    max = Math.max(Object.keys(item instanceof Object ? item : {}).length, max)
  })
  return max
}

const addHeaderBar = (num: number): string => {
  let text = '<th class="bar index"></th>'
  for (let i = 1; i <= num + 1; i++) {
    text += `<th class='bar'>${getWordName(i)}</th>`
  }
  return `${text}`
}

const init = async () => {
  loaded.value = false
  let num = 1
  const url = new URL(props.data, import.meta.url)
  const buffer = await fetch(url).then((res) => res.arrayBuffer())
  const workbook = XLSX.read(buffer, { type: 'array' })
  const sheet = workbook.Sheets[workbook.SheetNames[currentExcel.value]]
  const json = XLSX.utils.sheet_to_json(sheet)
  const col = getExcelHeaderCol(json)
  const sheetHtml = XLSX.utils.sheet_to_html(sheet)
  const addIndex = sheetHtml.replace(/<tr>/g, () => `<tr><td class='bar index'>${num++}</td>`)
  excelHtml.value = addIndex.replace(/<table>/g, () => `<table><thead><tr>${addHeaderBar(col)}</tr></thead>`)
  excelTabs.value = workbook.SheetNames
  excelViewDom.value?.scrollTo(0, 0)
  loaded.value = true
}

const handleSelectTab = (index: number) => {
  currentExcel.value = index
  init()
}

watch(() => props.data, init, { immediate: true, deep: true })
</script>

<style lang="scss">
@import '@/assets/scss/mixin';

.wps-excel {
  .excel-view {
    width: calc(100% - 20px);
    height: calc(100% - 26px - 78px - 6px * 2 - 30px);
    overflow: auto;
    @include scroll-bar;
  }

  .loading {
    position: absolute;
    z-index: 10;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
  }

  .excel-tabs {
    padding-left: 100px;
    box-sizing: border-box;
    height: 30px;
    display: flex;
    align-items: flex-start;

    > li {
      padding: 0 10px;
      display: flex;
      align-items: center;
      height: 26px;
      border-radius: 0 0 4px 4px;
      border: 1px solid transparent;
      border-top: none;

      &.checked {
        color: rgb(5, 124, 82);
        border-color: rgb(219, 219, 219);
        background-color: #fff;
      }
    }
  }

  table {
    border-collapse: collapse;
    box-sizing: border-box;
    width: 100%;
    background-color: #fff;
    position: relative;

    th {
      min-width: 80px;
      border: none !important;
      position: sticky;
      top: 0;
    }

    td,
    th {
      border: 1px solid rgb(230, 230, 230);

      &.bar {
        padding: 0 5px;
        background-color: rgb(238, 238, 238);
        text-align: center;
      }

      &.index {
        min-width: auto !important;
      }
    }
  }
}
</style>
